package com.hoapital.outpbillwork.module.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hoapital.outpbillwork.module.entity.*;
import com.hoapital.outpbillwork.module.mapper.*;
import com.hoapital.outpbillwork.module.service.OutpOrderDescService;
import com.hospital.api.RemoteBillService;
import com.hospital.common.core.constants.AllFinalValueUtils;
import com.hospital.common.core.exception.ExceptionHelp;
import com.hospital.common.core.exception.ExceptionHelpEnum;
import com.hospital.common.core.function.PushMessage;
import com.hospital.common.core.module.controller.dto.BillDto;
import com.hospital.common.core.module.controller.dto.ClinicItem;
import com.hospital.common.core.module.controller.dto.ClinicType;
import com.hospital.common.core.module.controller.vo.Receive;
import com.hospital.common.core.module.controller.vo.RefundBillDetailVo;
import com.hospital.common.core.module.controller.vo.RefundBillVo;
import com.hospital.common.core.module.entity.WxPayEntity;
import com.hospital.common.core.result.ErrorTip;
import com.hospital.common.core.result.SuccessTip;
import com.hospital.common.core.result.Tip;
import com.hospital.common.core.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.binding.BindingException;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.io.IOError;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * ¿ªµ¥Ö÷¼ÇÂ¼ 服务实现类
 * </p>
 *
 * @author lvyao
 * @since 2021-03-01
 */
@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class OutpOrderDescServiceImpl extends ServiceImpl<OutpOrderDescMapper, OutpOrderDesc> implements OutpOrderDescService {

    @Resource
    private OutpOrderDescMapper outpOrderDescMapper;

    @Resource
    private ExamMasterMapper examMasterMapper;

    @Resource
    private ExamAppointsMapper examAppointsMapper;

    @Resource
    private ExamItemsMapper examItemsMapper;

    @Resource
    private LabTestMasterMapper labTestMasterMapper;

    @Resource
    private DrugPrescMasterMapper drugPrescMasterMapper;

    @Resource
    private LabTestItemsMapper labTestItemsMapper;

    @Resource
    private ClinicVsChargeMapper clinicVsChargeMapper;

    @Resource
    private OutpOrderDescTempMapper outpOrderDescTempMapper;

    @Resource
    private OutpBillItemsTempMapper outpBillItemsTempMapper;

    @Resource
    private OutpDoctorAssistantMapper outpDoctorAssistantMapper;

    @Resource
    private OutpDoctorPrescItemsMapper outpDoctorPrescItemsMapper;

    @Resource
    private OutpDoctorPrescMasterMapper outpDoctorPrescMasterMapper;

    @Resource
    private OutpPrepayRcptTempMapper outpPrepayRcptTempMapper;

    @Resource
    private AppConfigerBaseinfoMapper appConfigerBaseinfoMapper;

    @Resource
    private OrderVsBillnoMapper orderVsBillnoMapper;

    @Resource
    private PushMessage pushMessage;


    @Override
    public int getDataOrder(String visitDate, String visitNo) {
        return outpOrderDescMapper.getDataOrder(visitDate, visitNo);
    }

    public OutpOrderDesc getDataOrders(String visitDate, String visitNo) {
        return outpOrderDescMapper.getDataOrders(visitDate, visitNo);
    }

    @Override
    public boolean saveAll(Receive receive) throws ExceptionHelp {
        List<WxPayEntity> wxPayEntityList = receive.getSettlePatientInfo();
        if (wxPayEntityList == null && wxPayEntityList.isEmpty()) {
            throw new ExceptionHelp(ExceptionHelpEnum.REQ_INFOR_NULL);
        }
        for (WxPayEntity wxPayEntity : wxPayEntityList) {

            OutpPrepayRcptTemp outpPrepayRcptTemp = getBillNo(wxPayEntity);
            String rcptNo = outpPrepayRcptTemp.getRcptNo();
//            String billNos = wxPayEntity.getBillNo().indexOf(",") > 0 ?  wxPayEntity.getBillNo() :outpPrepayRcptTemp.getBillNo();
            String billNos = outpPrepayRcptTemp.getBillNo();
            String[] billNoList = billNos.split(",");

            Map<String, String> hl7InterConfig = getHl7InterConfig(receive.getTaskId());
            String filePath = hl7InterConfig.get("filePath");
            String postHl7Url = hl7InterConfig.get("postHl7Url");
            String xmlHl7Url = hl7InterConfig.get("xmlHl7Url");

            //获取有HL7消息的拼接字符串
            List<String> guidAllList = new ArrayList<>();
            //获取到的处方等形成的文件
            List<String> billNoListHl7 = new ArrayList<>();
            if ((billNoList != null && billNoList.length > 0) ||
                    (wxPayEntity.getClinicTypeList() != null && wxPayEntity.getClinicTypeList().isEmpty() && wxPayEntity.getClinicTypeList().size() > 0)) {
                //组装收费信息模板计费
                BillDto billDto = new BillDto();
                String outpOrInp = "0" + outpPrepayRcptTemp.getInpOrOutp();
                billDto.setOutpOrInp(outpOrInp);
                receive.setOutpOrInp(outpOrInp);
                billDto.setHospitalCode(receive.getHospitalCode());
                billDto.setSettleFlag(outpPrepayRcptTemp.getSettleFlag());
                billDto.setHospitalName(receive.getHospitalName());
                receive.getSettlePatientInfo().get(receive.getSettlePatientInfo().indexOf(wxPayEntity)).setBillNo(billNos);
                receive.getSettlePatientInfo().get(receive.getSettlePatientInfo().indexOf(wxPayEntity)).setRcptNo(rcptNo);
                receive.getSettlePatientInfo().get(receive.getSettlePatientInfo().indexOf(wxPayEntity)).setOrderNo(outpPrepayRcptTemp.getOrderNo());
                billDto.setSettlePatientInfo(receive.getSettlePatientInfo());
                List<ClinicType> clinicTypeList = new ArrayList<>();
                OutpOrderDescTemp outpOrderDescTemp = null;

                if (billNoList != null && billNoList.length > 0) {
                    List<Object> list = getList(new QueryWrapper<OutpOrderDesc>(), billNoList[0], OutpOrderDesc.class);
                    if (list != null && list.size() > 0) {
                        throw new ExceptionHelp(ExceptionHelpEnum.BILL_OLD);
                    }
                    List<Object> objectList = getList(new QueryWrapper<OutpOrderDescTemp>(), billNoList[0], OutpOrderDescTemp.class);
                    if (objectList == null || objectList.isEmpty() || objectList.size() == 0) {
                        throw new ExceptionHelp(ExceptionHelpEnum.BILL_CHECK_OLD);
                    }
                    outpOrderDescTemp = (OutpOrderDescTemp) objectList.get(0);

                    //获取计费的门诊单号并处理不同医嘱类别的特殊表数据
                    for (String billNo : billNoList) {
                        Map<String, Object> map = commBill(receive, billNo);
                        List<ClinicType> clinicTypeList1 = (List<ClinicType>) map.get("clinicTypeList");
                        List<String> guidList = (List<String>) map.get("guidList");
                        clinicTypeList.addAll(clinicTypeList1);
                        guidAllList.addAll(guidList.stream().distinct().collect(Collectors.toList()));
                        billNoListHl7.add(filePath + billNo + ".xml");
                    }
                }
                try {
                    clinicTypeList.addAll(wxPayEntity.getClinicTypeList() == null ? null : wxPayEntity.getClinicTypeList());
                } catch (NullPointerException e) {
                }
                String chargeType = null;
                String patientId = outpOrderDescTemp == null ? wxPayEntity.getPatientId() : outpOrderDescTemp.getPatientId();
                String outpID = outpOrderDescTemp == null ? wxPayEntity.getOutpId() : String.valueOf(outpOrderDescTemp.getOutpId());
                receive.getSettlePatientInfo().get(receive.getSettlePatientInfo().indexOf(wxPayEntity)).setPatientId(patientId);
                billDto.setPatientId(patientId);
                billDto.setOutpId(outpID);
                chargeType = outpID == null || outpID.trim().equals("") ? clinicVsChargeMapper.getPatChargeType(patientId) : clinicVsChargeMapper.getChargeType(patientId, outpID);
                if (chargeType == null || chargeType.isEmpty()) {
                    chargeType = "自费";
                }
                billDto.setChargeType(chargeType);
                billDto.setClinicTypeList(clinicTypeList);
//                boolean sendBill = sendBill(billDto);
                boolean sendBill = pushMessage.sendBillMsg(billDto, outpOrderDescTempMapper.getBillUrl());
                if (!sendBill) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    throw new ExceptionHelp(ExceptionHelpEnum.FILED_REQ_BILL_SERVER);
                }
            }
            //推送计费消息到检验、检查
//            if (receive.getTaskId().equals(AllFinalValueUtils.TEST)||receive.getTaskId().equals(AllFinalValueUtils.EXAM)) {
            //处方的计费不从此处推送，通过Kafka监听数据推送  billNoListHl7 暂时不加入此接口
//            filePath += outpPrepayRcptTemp.getOrderNo() + ".xml" + "," + String.join(",", guidAllList)+ "," +  String.join(",",billNoListHl7);
            filePath += outpPrepayRcptTemp.getOrderNo() + ".xml" + "," + String.join(",", guidAllList);
            try {
                pushMessage.sendLabApplyInfo(receive.getHospitalCode(), receive.getHospitalName(), xmlHl7Url, filePath, postHl7Url, "1");
            } catch (Exception e) {
                //此处异常不处理，发送计费可以补充推送，不做回滚，发送失败的会插入表中补充推送，若回滚，计费和结算成功的消息不能回滚
            }
//            }
        }
        return true;
    }


    /**
     * 门诊计费单个订单业务数据处理 一个billno一次调用 也是收费信息模板计费
     *
     * @param receive
     * @param billNo
     * @return
     */
    public Map<String, Object> commBill(Receive receive, String billNo) throws ExceptionHelp {
        Map<String, Object> map = new HashMap<>();
        List<String> guidList = new ArrayList<>();
        List<ClinicType> clinicTypeList = new ArrayList<>();
        //获取此单号的所有收费项目
        List<Object> itemList = getList(new QueryWrapper<OutpDoctorAssistant>(), billNo, OutpDoctorAssistant.class);
        if (itemList.isEmpty()) {
            itemList = getList(new QueryWrapper<OutpDoctorPrescItems>(), billNo, OutpDoctorPrescItems.class);
        }
        if (itemList.isEmpty()) {
            throw new ExceptionHelp(ExceptionHelpEnum.ALL_ONE_BILL);
        }

        List<Object> outpOrderDescTempList = getList(new QueryWrapper<OutpOrderDescTemp>(), billNo, OutpOrderDescTemp.class);
        if (itemList.isEmpty() || outpOrderDescTempList.size() > 1) {
            throw new ExceptionHelp(ExceptionHelpEnum.ALL_ONE_BILL_ORDER);
        }
        ClinicType clinicType = new ClinicType();
        String type = null;
        List<ClinicItem> clinicItemList = new ArrayList<>();
        OutpOrderDescTemp outpOrderDescTemp = (OutpOrderDescTemp) outpOrderDescTempList.get(0);

        //更新处置表数据失败
        if (outpOrderDescTemp.getPrescIndicator() != 1 && outpDoctorAssistantMapper.updateFlag(billNo.substring(0, 14), billNo.substring(14), "1") < 0) {
            throw new ExceptionHelp(ExceptionHelpEnum.UPDATE_OUTP_Assis);
        }
        if (outpOrderDescTemp.getPrescIndicator() == 1) {
            //更新医嘱处方表中计费标记
            if (!drugPrescMasterMapper.updateChargeFlag(billNo.substring(0, 14), billNo.substring(14))) {
                throw new ExceptionHelp(ExceptionHelpEnum.UPDATE_OUTP_PRESC);
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            //更新药品处方表中处方标记 20220323 修改处方未审方（即drug_presc_master和drug_presc_detial无数据）的数据也能计费处方
            if (drugPrescMasterMapper.updatePrescStatus(billNo.substring(0, 14), billNo.substring(14), "0000", simpleDateFormat.format(new Date()), "计费") < 0) {
                throw new ExceptionHelp(ExceptionHelpEnum.UPDATE_OUTP_DRUG_PRESC);
            }
        } else {
            if (outpOrderDescTemp.getOrderType() != null && !outpOrderDescTemp.getOrderType().equals("")
                    && (outpOrderDescTemp.getOrderType().equals("C") || outpOrderDescTemp.getOrderType().equals("D"))) {
                if (outpOrderDescTemp.getOrderType().equals("C")) {
                    updateLab(billNo);
                } else {
                    updateExam(billNo);
                }
            }
        }
        for (Object receiveDate : itemList) {
            String itemClass;
            String itemCode;
            String performedBy;
            BigDecimal amount;
            String itemSpec;
            Date visitDate;
            Integer visitNo;
            if (outpOrderDescTemp.getPrescIndicator() == 1) {
                OutpDoctorPrescItems outpDoctorPrescItems = (OutpDoctorPrescItems) receiveDate;
                itemClass = outpDoctorPrescItems.getItemClass();
                itemCode = outpDoctorPrescItems.getPhamCode();
                performedBy = outpDoctorPrescItems.getPerformedBy();
                itemSpec = outpDoctorPrescItems.getPhamSpec() + outpDoctorPrescItems.getFirmId();
                amount = outpDoctorPrescItems.getAmount();
                visitDate = outpDoctorPrescItems.getVisitDate();
                visitNo = outpDoctorPrescItems.getVisitNo();
            } else {
                OutpDoctorAssistant outpDoctorAssistant = (OutpDoctorAssistant) receiveDate;
                itemClass = outpDoctorAssistant.getItemClass();
                itemCode = outpDoctorAssistant.getItemCode();
                performedBy = outpDoctorAssistant.getPerformedBy();
                itemSpec = outpDoctorAssistant.getItemSpec();
                amount = outpDoctorAssistant.getAmount();
                visitDate = outpDoctorAssistant.getVisitDate();
                visitNo = outpDoctorAssistant.getVisitNo();
                if (outpDoctorAssistant.getGuid() != null && outpDoctorAssistant.getGuid().length() > 0) {
                    String hl7MessageGuid = outpDoctorAssistant.getGuid() + "-" + visitNo;
                    guidList.add(hl7MessageGuid);
                }
            }
            if (type != null && !type.equals(itemClass)) {
                clinicType.setType(type == null ? itemClass : type);
                clinicType.setClinicItemList(clinicItemList);
                clinicTypeList.add(clinicType);
                clinicType = new ClinicType();
                clinicItemList = new ArrayList<>();
            }
            clinicType.setType(itemClass);
            List<ClinicVsCharge> clinicVsChargeList = clinicVsChargeMapper.getOrderItemBillDetail(itemClass, itemCode);
            if (itemClass.equals("I") || itemClass.equals("A") || itemClass.equals("B")) {
                ClinicVsCharge clinicVsCharge = new ClinicVsCharge();
                clinicVsCharge.setAmount(new BigDecimal(1));
                clinicVsCharge.setChargeItemClass(itemClass);
                clinicVsCharge.setChargeItemCode(itemCode);
                clinicVsCharge.setChargeItemNo(1);
                clinicVsCharge.setChargeItemSpec(itemSpec);
                clinicVsCharge.setClinicItemClass(itemClass);
                clinicVsCharge.setClinicItemCode(itemCode);
                clinicVsChargeList.add(clinicVsCharge);
            }
            if (clinicVsChargeList != null && clinicVsChargeList.size() > 0) {
                ClinicItem clinicItem = new ClinicItem();
                clinicItem.setClinicItemCode(itemCode);
                clinicItem.setPerformedBy(performedBy);
                clinicItem.setItemSpec(itemSpec);
                clinicItem.setPrimaryDate(DateUtil.format(visitDate, "yyyy-MM-dd HH:mm:ss"));
                clinicItem.setPrimaryNo(String.valueOf(visitNo));
                clinicItem.setOrderedBy(outpOrderDescTemp.getOrderedByDept());
                clinicItem.setOperatorNo("0000");
                //删除单个收费项目收费临时表中数据门诊删除
                List<String> deleteBillItemList = new ArrayList<>();
                for (ClinicVsCharge clinicVsCharge : clinicVsChargeList) {
                    deleteBillItemList.add(clinicVsCharge.getChargeItemCode());
                }
                int deleteBillItems = outpBillItemsTempMapper.deleteBillItems(billNo.substring(0, 14), billNo.substring(14), deleteBillItemList);
                if (deleteBillItems < 0) {
                    throw new ExceptionHelp(ExceptionHelpEnum.FILED_DELETE_BILL);
                }
                clinicItem.setAmount(amount);
                clinicItemList.add(clinicItem);
                type = itemClass;
            } else {
                throw new ExceptionHelp(ExceptionHelpEnum.PRESC_BILL_ITEM);
            }
        }
        clinicType.setClinicItemList(clinicItemList);
        clinicTypeList.add(clinicType);

        //医嘱正式表中是否有数据,以及明细收费临时表中数据是否已经删除完
        int dataOrder = outpOrderDescMapper.getDataOrder(billNo.substring(0, 14), billNo.substring(14));
        List<OutpBillItemsTemp> outpBillItemsTemp = outpBillItemsTempMapper.getOutpBillItemsTemp(billNo.substring(0, 14), billNo.substring(14));

        //无主表数据则插入医嘱主表门诊
        if (dataOrder == 0 && receive.getOutpOrInp().equals("01")) {
            //获取医嘱临时表中数据并赋值给医嘱正式表
            OutpOrderDesc outpOrderDesc = new OutpOrderDesc();
            BeanUtils.copyProperties(outpOrderDescTemp, outpOrderDesc);
            outpOrderDesc.setRcptNo(receive.getSettlePatientInfo().get(0).getRcptNo());
            Integer insert = outpOrderDescMapper.insert(outpOrderDesc);
            if (insert < 0) {
                throw new ExceptionHelp(ExceptionHelpEnum.INSERT_ORDER_DESC);
            }
        }
        if ((outpBillItemsTemp == null || outpBillItemsTemp.isEmpty()) && receive.getOutpOrInp().equals("01")) {
            //费用临时表中数据若已删除完成则删除临时医嘱主表数据
            int deletTemp = outpOrderDescTempMapper.deletTemp(billNo.substring(0, 14), billNo.substring(14));
            if (deletTemp < 0) {
                throw new ExceptionHelp(ExceptionHelpEnum.DELETE_ORDER_DESC_TEMP);
            }
        }
        map.put("clinicTypeList", clinicTypeList);
        map.put("guidList", guidList);
        return map;
    }

    /**
     * 根据条件以及类对象名称获取数据集合
     *
     * @param queryWrapper
     * @param billNo
     * @param objectClass
     * @return
     */
    @Override
    public List<Object> getList(QueryWrapper queryWrapper, String billNo, Class objectClass) {
        String simpleName = objectClass.getSimpleName();
        queryWrapper.eq(AllFinalValueUtils.OUTP_VISIT_NO, billNo.substring(14));
        queryWrapper.apply("  visit_date = to_date({0},'yyyy-mm-dd hh24:mi:ss')", billNo.substring(0, 14));
        List<Object> objectList;
        if (simpleName.equals(AllFinalValueUtils.OUTP_DOC_ASS)) {
            objectList = outpDoctorAssistantMapper.selectList(queryWrapper);
        } else if (simpleName.equals(AllFinalValueUtils.OUTP_BILL_ITEMS_TEMP)) {
            objectList = outpBillItemsTempMapper.selectList(queryWrapper);
        } else if (simpleName.equals(AllFinalValueUtils.OUTP_DOC_PRESC_ITEMS)) {
            objectList = outpDoctorPrescItemsMapper.selectList(queryWrapper);
        } else if (simpleName.equals(AllFinalValueUtils.OUTP_ORDER_DESC)) {
            objectList = outpOrderDescMapper.selectList(queryWrapper);
        } else if (simpleName.equals(AllFinalValueUtils.LAB_TEST_MASTER)) {
            objectList = labTestMasterMapper.selectList(queryWrapper);
        } else {
            objectList = outpOrderDescTempMapper.selectList(queryWrapper);
        }
        return objectList;
    }

    @Override
    public OutpOrderDesc getOrderTempDate(String substring, String substring1) {
        return outpOrderDescMapper.getDataOrders(substring, substring1);
    }

    @Override
    public Tip refundBill(RefundBillVo refundBillVo, RemoteBillService remoteBillService) {

        Timestamp sysdate = outpDoctorPrescMasterMapper.getSysdate();
        String visitNo = labTestMasterMapper.getVisitNo();
        List<OutpOrderDesc> outpOrderDescs = outpOrderDescMapper.selectList(new QueryWrapper<OutpOrderDesc>().
                apply(AllFinalValueUtils.REFUND_BILL, refundBillVo.getNumberNo()));
        if (outpOrderDescs.isEmpty()) {
            return new ErrorTip(ExceptionHelpEnum.REFUND_ORDER_NULL);
        }

        String winno = outpOrderDescMapper.getWinno();
        String currentRcptNo;
        try {
            currentRcptNo = String.valueOf(outpOrderDescMapper.getMaxRcptNo(winno));
        } catch (BindingException b) {
            currentRcptNo = winno + "000000";
        }
        if (currentRcptNo.equals(winno + "999999")) {
            return new ErrorTip(ExceptionHelpEnum.REFUND_RCPT_GET_ERR);
        } else {
            currentRcptNo = String.valueOf(Integer.parseInt(currentRcptNo) + 1);
        }
        refundBillVo.setRefundRcpt(currentRcptNo);
        List<RefundBillDetailVo> refundBillDetailVos = new ArrayList<>();
        refundBillVo.setNumberNo(outpOrderDescs.get(0).getRcptNo());
        String finalCurrentRcptNo = currentRcptNo;
        outpOrderDescs.stream().forEach(outpOrderDesc -> {
            RefundBillDetailVo refundBillDetailVo = new RefundBillDetailVo();
            refundBillDetailVo.setPrimaryKey(DateUtil.formatDate(outpOrderDesc.getVisitDate(), "yyyyMMddHHmmss"));
            refundBillDetailVo.setSlaveKey(String.valueOf(outpOrderDesc.getVisitNo()));
            refundBillDetailVo.setSlaveKeyNew(visitNo);
            refundBillDetailVo.setPrimaryKeyNew(DateUtil.dateToStr(sysdate, "yyyyMMddHHmmss"));
            outpOrderDesc.setVisitDate(sysdate);
            outpOrderDesc.setRcptNo(finalCurrentRcptNo);
            outpOrderDesc.setVisitNo(Integer.parseInt(visitNo));
            outpOrderDesc.setOperatorNo(refundBillVo.getOperNo());
            outpOrderDesc.setOperatorNo(AllFinalValueUtils.ALL_OPERATOR);
            try {
                Integer insert = outpOrderDescMapper.insert(outpOrderDesc);
            } catch (Exception e) {
                ExceptionHelpEnum.INSER_ORDER_REFUND.setMessage(e.getMessage());
                throw new ExceptionHelp(ExceptionHelpEnum.INSER_ORDER_REFUND);
            }
            refundBillDetailVos.add(refundBillDetailVo);
        });
        refundBillVo.setRefundBillDetailList(refundBillDetailVos);
        try {
            Tip sendBill = remoteBillService.refundcharge(JSONObject.toJSONString(refundBillVo),null);
            if (sendBill.getCode()!=200) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw new ExceptionHelp(ExceptionHelpEnum.FILED_REQ_BILL_SERVER);
            }
        } catch (IOError e) {
            throw new ExceptionHelp(ExceptionHelpEnum.SERVICE_ERR);
        }
        return new SuccessTip();
    }

    /**
     * 更新检验相关数据
     *
     * @param billNo
     * @return
     */
    private boolean updateLab(String billNo) throws ExceptionHelp {
        String testNo = labTestMasterMapper.getTestNo(billNo.substring(0, 14), billNo.substring(14));
        if (testNo != null) {
            QueryWrapper<LabTestItems> labTestItemsEntityWrapper = new QueryWrapper<>();
            labTestItemsEntityWrapper.eq("test_no", testNo);
            List<LabTestItems> labTestItemsList = labTestItemsMapper.selectList(labTestItemsEntityWrapper);
            if (labTestItemsList != null && !labTestItemsList.isEmpty() && labTestItemsList != null && !labTestItemsList.isEmpty()) {
                for (LabTestItems labTestItems : labTestItemsList) {
                    //更新单个检验项目收费标记
                    int updateChargeFlag1 = labTestItemsMapper.updateChargeFlag(testNo, labTestItems.getItemCode());
                    if (updateChargeFlag1 < 0) {
                        throw new ExceptionHelp(ExceptionHelpEnum.UPDATE_ITEM_BILL_CHARGE_FLAG);
                    }
                }
                //所有项目收费标记都完成了再更新主表收费标记
                int testNoAllItemChargeFlag = labTestItemsMapper.getTestNoAllItemChargeFlag(testNo);
                if (testNoAllItemChargeFlag == 0) {
                    int updateChargeFlag = labTestMasterMapper.updateChargeFlag(testNo);
                    if (updateChargeFlag < 0) {
                        throw new ExceptionHelp(ExceptionHelpEnum.UPDATE_ITEM_BILL_CHARGE_FLAG);
                    }
                }
            } else {
                throw new ExceptionHelp(ExceptionHelpEnum.REQ_INFOR_ERRE);
            }
        } else {
            throw new ExceptionHelp(ExceptionHelpEnum.REQ_INFOR_NULL);
        }
        return true;
    }

    private boolean updateExam(String billNo) throws ExceptionHelp {
        String examNo = outpDoctorAssistantMapper.getApplyNo(billNo.substring(0, 14), billNo.substring(14), "1");
        if (examNo != null && examNo != "") {
            List<ExamItems> examItemsList = examItemsMapper.selectList(new QueryWrapper<ExamItems>().eq("exam_no", examNo));
            if (examItemsList != null && !examItemsList.isEmpty()) {
                ExamAppoints examAppoints = examAppointsMapper.selectById(examNo);
                //所有项目收费标记都完成了再删除预约表数据插入检查主表数据
                ExamMaster examMaster = new ExamMaster();
                BeanUtils.copyProperties(examAppoints, examMaster);
                examMaster.setChargeIndicator(1);
                if (examMasterMapper.insert(examMaster) > 0) {
                    if (examAppointsMapper.delete(new QueryWrapper<ExamAppoints>().eq("exam_no", examNo)) <= 0) {
                        throw new ExceptionHelp(ExceptionHelpEnum.DELETE_REQ_INFO);
                    }
                } else {
                    throw new ExceptionHelp(ExceptionHelpEnum.FILED_INSERT_EXAM_MASTER);
                }
                return true;
            }
        } else {
            throw new ExceptionHelp(ExceptionHelpEnum.EXAM_BILL_ITEM);
        }
        return false;
    }

    public OutpPrepayRcptTemp getBillNo(WxPayEntity wxPayEntity) throws ExceptionHelp {
        OutpPrepayRcptTemp outpPrepayRcptTemp = null;
//        if (wxPayEntity.getCreateChannel().equals("2")) {
        QueryWrapper<OutpPrepayRcptTemp> outpPrepayRcptTempQueryWrapper = new QueryWrapper<>();
//            String patientId = wxPayEntity.getPatientId();
        String billNo = wxPayEntity.getBillNo();
        if (billNo == null || billNo.trim().equals("")) {
            throw new ExceptionHelp(ExceptionHelpEnum.BILL_NO_GET_ERROR);
        }
        outpPrepayRcptTempQueryWrapper.apply("settle_flag <> '2' and order_no = {0}", billNo);
        List<OutpPrepayRcptTemp> outpPrepayRcptTempList = outpPrepayRcptTempMapper.selectList(outpPrepayRcptTempQueryWrapper);
        QueryWrapper<OrderVsBillno> orderVsBillnoQueryWrapper = new QueryWrapper<>();
        orderVsBillnoQueryWrapper.eq("order_no", billNo);
        List<OrderVsBillno> orderVsBillnoList = orderVsBillnoMapper.selectList(orderVsBillnoQueryWrapper);
        String collect = orderVsBillnoList.stream().map(p -> p.getBillNo()).collect(Collectors.joining(","));
        if (outpPrepayRcptTempList == null || outpPrepayRcptTempList.isEmpty() || outpPrepayRcptTempList.size() > 1) {
            if (wxPayEntity.getClinicTypeList() == null || wxPayEntity.getClinicTypeList().size() <= 0) {
                throw new ExceptionHelp(ExceptionHelpEnum.BILL_NO_GET_ERROR);
            }
            if (wxPayEntity.getPatientId() != null || !wxPayEntity.getPatientId().equals("")) {
                String patientId = wxPayEntity.getPatientId();
                outpPrepayRcptTemp = new OutpPrepayRcptTemp();
                outpPrepayRcptTemp.setPatientId(patientId);
                outpPrepayRcptTemp = setOutpPrepayRcptTempValue(outpPrepayRcptTemp);
                outpPrepayRcptTemp.setBillNo(wxPayEntity.getBillNo());
                return outpPrepayRcptTemp;
            }
            throw new ExceptionHelp(ExceptionHelpEnum.ORDER_GET_MORE_NULL);
        }
        outpPrepayRcptTemp = outpPrepayRcptTempList.get(0);
        outpPrepayRcptTemp = setOutpPrepayRcptTempValue(outpPrepayRcptTemp);
        outpPrepayRcptTemp.setBillNo(collect);
//        } else {
//            outpPrepayRcptTemp = new OutpPrepayRcptTemp();
//            outpPrepayRcptTemp = setOutpPrepayRcptTempValue(outpPrepayRcptTemp);
//            outpPrepayRcptTemp.setBillNo(outpPrepayRcptTemp.getOrderNo());
//        }
        return outpPrepayRcptTemp;
    }

    /**
     * 获取门诊订单记录数据
     *
     * @param outpPrepayRcptTemp
     * @return
     */
    public OutpPrepayRcptTemp setOutpPrepayRcptTempValue(OutpPrepayRcptTemp outpPrepayRcptTemp) {
        AppConfigerBaseinfo appConfigerBaseinfo = getAppConfigerBaseinfo("*", "AUTO_SETTLE_WIN");
        String parainitValue = appConfigerBaseinfo.getParainitValue().trim();
        String parameterScope = appConfigerBaseinfoMapper.getSettleNo();
//        String parameterScope = appConfigerBaseinfo.getParameterScope().trim();
//        String paraScope = String.valueOf(Integer.parseInt(parameterScope) + 1);
//        appConfigerBaseinfo.setParameterScope(paraScope);
//        try {
//            Integer update = appConfigerBaseinfoMapper.update(appConfigerBaseinfo, new QueryWrapper<AppConfigerBaseinfo>().apply(" app_name = '*' and parameter_name = 'AUTO_SETTLE_WIN'"));
//        } catch (Exception e) {
//            throw new ExceptionHelp(ExceptionHelpEnum.UPDATE_AUTO_SETTLE_NO_FILAD);
//        }
//        String rcptno = parainitValue + String.format("%06d", Integer.parseInt(paraScope));
        String rcptno = parainitValue + String.format("%06d", Integer.parseInt(parameterScope));
        outpPrepayRcptTemp.setRcptNo(rcptno);
        return outpPrepayRcptTemp;

    }

    /**
     * 按程序名称以及参数名称获取配置对象
     *
     * @param appName
     * @param paraName
     * @return
     * @throws ExceptionHelp
     */
    protected AppConfigerBaseinfo getAppConfigerBaseinfo(String appName, String paraName) throws ExceptionHelp {
        List<AppConfigerBaseinfo> appConfigerBaseinfoList = appConfigerBaseinfoMapper.selectList(new QueryWrapper<AppConfigerBaseinfo>().
                apply(" app_name = '" + appName + "' and parameter_name = '" + paraName + "'"));
        if (appConfigerBaseinfoList == null || appConfigerBaseinfoList.isEmpty() || appConfigerBaseinfoList.size() > 1) {
            throw new ExceptionHelp(ExceptionHelpEnum.BILL_NO_GET_ERROR);
        }
        return appConfigerBaseinfoList.get(0);
    }

    public Map<String, String> getHl7InterConfig(String getHl7LabMessage) {
        Map<String, String> map = new HashMap<>();
        QueryWrapper<AppConfigerBaseinfo> appConfigerBaseinfoQueryWrapper1 = new QueryWrapper<>();
        appConfigerBaseinfoQueryWrapper1.eq("app_name", "*");
        List<AppConfigerBaseinfo> appConfigerBaseinfoList = appConfigerBaseinfoMapper.selectList(appConfigerBaseinfoQueryWrapper1);
        String filePath = null;
        String postHl7Url = null;
        String xmlHl7Url = null;
        try {
            filePath = appConfigerBaseinfoList.stream().filter(appConfigerBaseinfo -> appConfigerBaseinfo.getParameterName().equals("XML_HL7_FILE")).collect(Collectors.toList()).get(0).getParainitValue();
            postHl7Url = appConfigerBaseinfoList.stream().filter(appConfigerBaseinfo -> appConfigerBaseinfo.getParameterName().equals(getHl7LabMessage == null || getHl7LabMessage.trim().equals("") || getHl7LabMessage.equals(AllFinalValueUtils.TEST) ? "WX_HL7_POST_URL" : "WX_HL7_EXAM_URL")).collect(Collectors.toList()).get(0).getParainitValue();
            xmlHl7Url = appConfigerBaseinfoList.stream().filter(appConfigerBaseinfo -> appConfigerBaseinfo.getParameterName().equals("XML_HL7_URL")).collect(Collectors.toList()).get(0).getParainitValue();
        } catch (Exception e) {
            throw new ExceptionHelp(ExceptionHelpEnum.GET_HL7_CONFIGER_ERR);
        }
        map.put("filePath", filePath);
        map.put("postHl7Url", postHl7Url);
        map.put("xmlHl7Url", xmlHl7Url);
        return map;
    }
}
